home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 2: Applications / Linux Cubed Series 2 - Applications.iso / math / gle-3.000 / gle-3 / gle / menu.c < prev    next >
C/C++ Source or Header  |  1995-02-07  |  51KB  |  1,439 lines

  1. #include "all.h"
  2. #include "color.h"
  3. #include "edt.h"
  4. #ifdef unix
  5.         #define SEEK_SET 0
  6. #endif
  7. #ifdef DJ                       /* a.r. */
  8.         #define SEEK_SET 0
  9.         #define clrscr ScreenClear
  10. #endif
  11. #ifdef EMXOS2                   /* a.r. */
  12.         #define SEEK_SET 0
  13.         extern unsigned long startPMSession(void);
  14.         extern unsigned long stopPMSession(unsigned long SessID);
  15.         extern unsigned long oldSession;
  16.         extern int text_saveOS2tmp(void);
  17.         extern int g_get_type(char *t);
  18.         char devtype[60];
  19. #endif
  20.  
  21. #ifdef __TURBOC__
  22.         #define DASHCHAR 249
  23.         #include "bios.h"
  24.         #include "conio.h"
  25.         #include "dir.h"
  26. #elif DJ                        /* a.r. */
  27.         #define DASHCHAR 249
  28.         #include <gppconio.h>
  29.         #include <dir.h>
  30. #elif EMXOS2                    /* a.r. */
  31.         #define INCL_DOS
  32.         #include <os2.h>
  33.         #include <conio.h>
  34.         #include <sys/types.h>
  35.         #include <sys/dir.h>
  36.         #define DASHCHAR 249
  37.         #define WHITE 15
  38.         #define BLACK 0
  39. #else
  40.         #define DASHCHAR '.'
  41.         #include "vaxconio.h"
  42. #endif
  43.  
  44. #define true (!false)
  45. #define false 0
  46. #define BEGINDEF extern
  47. #include "begin.h"
  48. #define BCOLOR BLUE
  49. #define FCOLOR MAGENTA
  50. #define HBCOLOR h_bcolor
  51. #define HVCOLOR h_fcolor
  52. #define VCOLOR WHITE
  53.  
  54. int h_bcolor;
  55. int h_fcolor;
  56. int getsize(void);
  57. char *tabtospace(char *s);
  58. int printdash(int i);
  59. char *gledir(char *s);
  60. int scr_menuval(void);
  61. int scr_menubg(void);
  62. int scr_menuhi(void);
  63. int scr_grey(void);
  64. int gle_redraw(void);
  65. int text_showerror(void);
  66. int text_save(void);
  67. int fner(char *s);
  68. char *strfile(char *s);
  69.  
  70. int vdelete(int i);
  71. int vinsert(int y, char *s);
  72. int m_ifsend(char *s);
  73. int m_sendline(void);
  74. int minit_extras(void);
  75. int minit_extras(void);
  76. int initmenu(void);
  77. int mystrlen(char *s);
  78. int pick_file(char *d, char *w);
  79. int ncpy(char *d, char *s, int n);
  80. int setvstr(char **d, char *s);
  81. int do_help(char *s);
  82. int text_inkey(void);
  83.  
  84. extern int ngtxt;
  85. extern char *(*gtxt)[];
  86.  
  87.  
  88. struct menu_struct { int x; int y; char *title; int width; int typ; int typ2;
  89.         char *val; char *help; };
  90. typedef struct menu_struct menutype;
  91. struct pmenu_struct {int ci; menutype *menu; };
  92. typedef struct pmenu_struct pmenutype;
  93. pmenutype pmenu[17];
  94. int setmenu(menutype *m,int x, int y, int typ, int typ2, int width, char *title
  95.         , char *val, char *help);
  96. int do_menu(pmenutype *p);
  97. int token_space(void);
  98. int extractmenu(void);
  99. int add_unrecognized(char *s);
  100. int fillinmenu(int nbegin);
  101. int nunrec;
  102.  
  103. #define  PTXT 0
  104. enum {MEND,MTEXT,MFILE,MTOGON,MTOGOFF,MSUB,MRETURN,MNULL};
  105. enum {SNORM,SROL,SNEXTS,SNEXT,SSTR,STOG,SS,SSIZE,SNOBOX,SAMOVE,SSOFF,SSNULL};
  106. menutype xnamesmenu[] = {
  107.         2,3,    "Xnames ",  64,MTEXT,SROL,PTXT,"xnames",
  108.         2,5,    "Xplaces ", 64,MTEXT,SROL,PTXT,"xplaces",
  109.         0,0,"",         0,MEND,0,0,""};
  110. menutype ynamesmenu[] = {
  111.         2,3,    "Ynames ",  64,MTEXT,SROL,PTXT,"ynames",
  112.         2,5,    "Yplaces ", 64,MTEXT,SROL,PTXT,"yplaces",
  113.         0,0,"",         0,MEND,0,0,""};
  114. menutype x2namesmenu[] = {
  115.         2,3,    "X2names ", 64,MTEXT,SROL,PTXT,"x2names",
  116.         2,5,    "X2places ",    64,MTEXT,SROL,PTXT,"x2places",
  117.         0,0,"",         0,MEND,0,0,""};
  118. menutype y2namesmenu[] = {
  119.         2,3,    "Y2names ", 64,MTEXT,SROL,PTXT,"y2names",
  120.         2,5,    "Y2places ",    64,MTEXT,SROL,PTXT,"y2places",
  121.         0,0,"",         0,MEND,0,0,""};
  122. menutype x2axismenu[] = {
  123.  
  124.         1,4,    "X2Title ", 27,MTEXT,SNEXTS,PTXT,"x2title",
  125.         37,4,   "Hei ",     4,MTEXT,0,PTXT,"x2title hei",
  126.         46,4,   "Dist ",    3,MTEXT,0,PTXT,"x2title dist",
  127.         55,4,   "Font " ,   4,MTEXT,0,PTXT,"x2title font",
  128.         65,4,   "Color ",   7,MTEXT,0,PTXT,"x2title color",
  129.  
  130.         1,6,    "X2axis ",  3,MTOGON,SSOFF,PTXT,"x2axis off",
  131.         13,6,   "Min ",     6,MTEXT,0,PTXT,"x2axis min",
  132.         24,6,   "Max ",     6,MTEXT,0,PTXT,"x2axis max",
  133.         35,6,   "Dticks ",  6,MTEXT,0,PTXT,"x2axis dticks",
  134.         49,6,   "Dsubticks ",   6,MTEXT,0,PTXT,"x2axis dsubticks",
  135.         66,6,   "LOG ",     3,MTOGOFF,SS,PTXT,"x2axis log",
  136.  
  137.         1,8,    "X2labels ",    3,MTOGOFF,SS,PTXT,"x2labels on",
  138.         15,8,   "Hei ",     4,MTEXT,0,PTXT,"x2labels hei",
  139.         24,8,   "Dist ",    4,MTEXT,0,PTXT,"x2labels dist",
  140.         34,8,   "Font ",    4,MTEXT,0,PTXT,"x2labels font",
  141.         44,8,   "Color ",   7,MTEXT,0,PTXT,"x2labels color",
  142.         59,8,   "",     5,MSUB,103,"Names","x2names",
  143.         0,0,"",         0,MEND,0,0,""};
  144.  
  145. menutype y2axismenu[] = {
  146.  
  147.         1,4,    "Y2Title ", 27,MTEXT,SNEXTS,PTXT,"y2title",
  148.         37,4,   "Hei ",     4,MTEXT,0,PTXT,"y2title hei",
  149.         46,4,   "Dist ",    3,MTEXT,0,PTXT,"y2title dist",
  150.         55,4,   "Font " ,   4,MTEXT,0,PTXT,"y2title font",
  151.         65,4,   "Color ",   7,MTEXT,0,PTXT,"y2title color",
  152.  
  153.  
  154.         1,6,    "Y2axis ",  3,MTOGON,SSOFF,PTXT,"y2axis off",
  155.         12,6,   "Min ",     6,MTEXT,0,PTXT,"y2axis min",
  156.         23,6,   "Max ",     6,MTEXT,0,PTXT,"y2axis max",
  157.         34,6,   "Dticks ",  6,MTEXT,0,PTXT,"y2axis dticks",
  158.         48,6,   "Dsubticks ",   6,MTEXT,0,PTXT,"y2axis dsubticks",
  159.         65,6,   "LOG ",     3,MTOGOFF,SS,PTXT,"y2axis log",
  160.  
  161.         1,8,    "Y2labels ",    3,MTOGOFF,SS,PTXT,"y2labels on",
  162.         15,8,   "Hei ",     4,MTEXT,0,PTXT,"y2labels hei",
  163.         24,8,   "Dist ",    4,MTEXT,0,PTXT,"y2labels dist",
  164.         34,8,   "Font ",    4,MTEXT,0,PTXT,"y2labels font",
  165.         44,8,   "Color ",   7,MTEXT,0,PTXT,"y2labels color",
  166.         59,8,   "",     4,MSUB,104,"Names","y2names",
  167.         0,0,"",         0,MEND,0,0,""};
  168. menutype fillmenu[] = {
  169.         2,3,    "Fill ",    60,MTEXT,SROL,PTXT,"fill",
  170.         2,5,    "Fill ",    60,MTEXT,SROL,PTXT,"fill",
  171.         2,7,    "Fill ",    60,MTEXT,SROL,PTXT,"fill",
  172.         2,9,    "Fill ",    60,MTEXT,SROL,PTXT,"fill",
  173.         2,11,   "Fill ",    60,MTEXT,SROL,PTXT,"fill",
  174.         0,0,"",         0,MEND,0,0,""};
  175. menutype barmenu[] = {
  176.         2,3,    "Bar ",     60,MTEXT,SROL,PTXT,"bar",
  177.         2,5,    "Bar ",     60,MTEXT,SROL,PTXT,"bar",
  178.         2,7,    "Bar ",     60,MTEXT,SROL,PTXT,"bar",
  179.         2,9,    "Bar ",     60,MTEXT,SROL,PTXT,"bar",
  180.         2,11,   "Bar ",     60,MTEXT,SROL,PTXT,"bar",
  181.         0,0,"",         0,MEND,0,0,""};
  182. menutype letmenu[] = {
  183.         2,3,    "Let ",     60,MTEXT,SROL,PTXT,"let",
  184.         2,5,    "Let ",     60,MTEXT,SROL,PTXT,"let",
  185.         2,7,    "Let ",     60,MTEXT,SROL,PTXT,"let",
  186.         2,9,    "Let ",     60,MTEXT,SROL,PTXT,"let",
  187.         2,11,   "Let ",     60,MTEXT,SROL,PTXT,"let",
  188.         0,0,"",         0,MEND,0,0,""};
  189. menutype xtramenu[] = {
  190.         2,3,    "Xtra ",        60,MTEXT,SROL,PTXT,"xtra",
  191.         2,5,    "Xtra ",        60,MTEXT,SROL,PTXT,"xtra",
  192.         2,7,    "Xtra ",        60,MTEXT,SROL,PTXT,"xtra",
  193.         2,9,    "Xtra ",        60,MTEXT,SROL,PTXT,"xtra",
  194.         2,11,   "Xtra ",        60,MTEXT,SROL,PTXT,"xtra",
  195.         0,0,"",         0,MEND,0,0,""};
  196. /* int x; int y; char *title; int width; int typ; int typ2; char *val; */
  197. menutype graphmenu[278] = {
  198.         1,1,    "Size ",    4,MTEXT,SSIZE,"24","size",
  199.         12,1,   "",     4,MTEXT,0,"18","size",
  200.         19,1,   "Position ",    4,MTEXT,SAMOVE,PTXT,"position",
  201.         34,1,   "",     4,MTEXT,SAMOVE,PTXT,"position",
  202. /*  42,1,   "Lwidth ",  4,MTEXT,0,PTXT,"lwidth", */
  203.         55,1,   "Border ",  3,MTOGON,SNOBOX,PTXT,"nobox",
  204.  
  205.         1,2,    "Title ",   27,MTEXT,SNEXTS,PTXT,"title",
  206.         37,2,   "Hei ",     4,MTEXT,0,PTXT,"title hei",
  207.         46,2,   "Dist ",    3,MTEXT,0,PTXT,"title dist",
  208.         55,2,   "Font " ,   4,MTEXT,0,PTXT,"title font",
  209.         65,2,   "Color ",   7,MTEXT,0,PTXT,"title color",
  210.  
  211.         1,3,    "XTitle ",  27,MTEXT,SNEXTS,PTXT,"xtitle",
  212.         37,3,   "Hei ",     4,MTEXT,0,PTXT,"xtitle hei",
  213.         46,3,   "Dist ",    3,MTEXT,0,PTXT,"xtitle dist",
  214.         55,3,   "Font " ,   4,MTEXT,0,PTXT,"xtitle font",
  215.         65,3,   "Color ",   7,MTEXT,0,PTXT,"xtitle color",
  216.  
  217.         1,4,    "YTitle ",  27,MTEXT,SNEXTS,PTXT,"ytitle",
  218.         37,4,   "Hei ",     4,MTEXT,0,PTXT,"ytitle hei",
  219.         46,4,   "Dist ",    3,MTEXT,0,PTXT,"ytitle dist",
  220.         55,4,   "Font " ,   4,MTEXT,0,PTXT,"ytitle font",
  221.         65,4,   "Color ",   7,MTEXT,0,PTXT,"ytitle color",
  222.  
  223.         1,5,    "Xaxis ",   3,MTOGON,SSOFF,PTXT,"xaxis off",
  224.         12,5,   "Min ",     6,MTEXT,0,PTXT,"xaxis min",
  225.         23,5,   "Max ",     6,MTEXT,0,PTXT,"xaxis max",
  226.         34,5,   "Dticks ",  6,MTEXT,0,PTXT,"xaxis dticks",
  227.         48,5,   "Dsubticks ",   6,MTEXT,0,PTXT,"xaxis dsubticks",
  228.         65,5,   "LOG ",     3,MTOGOFF,SS,PTXT,"xaxis log",
  229.  
  230.         1,6,    "Yaxis ",   3,MTOGON,SSOFF,PTXT,"yaxis off",
  231.         12,6,   "Min ",     6,MTEXT,0,PTXT,"yaxis min",
  232.         23,6,   "Max ",     6,MTEXT,0,PTXT,"yaxis max",
  233.         34,6,   "Dticks ",  6,MTEXT,0,PTXT,"yaxis dticks",
  234.         48,6,   "Dsubticks ",   6,MTEXT,0,PTXT,"yaxis dsubticks",
  235.         65,6,   "LOG ",     3,MTOGOFF,SS,PTXT,"yaxis log",
  236.  
  237.         1,7,    "Xlabels ", 3,MTOGON,SSOFF,PTXT,"xlabels off",
  238.         14,7,   "Hei ",     4,MTEXT,0,PTXT,"xlabels hei",
  239.         23,7,   "Dist ",    4,MTEXT,0,PTXT,"xlabels dist",
  240.         33,7,   "Font ",    4,MTEXT,0,PTXT,"xlabels font",
  241.         43,7,   "Color ",   7,MTEXT,0,PTXT,"xlabels color",
  242.         58,7,   "",     6,MSUB,101,"Xnames","xnames",
  243.         66,7,   "Grid ",    3,MTOGOFF,SS,PTXT,"xaxis grid",
  244.  
  245.         1,8,    "Ylabels ", 3,MTOGON,SSOFF,PTXT,"ylabels off",
  246.         14,8,   "Hei ",     4,MTEXT,0,PTXT,"ylabels hei",
  247.         23,8,   "Dist ",    4,MTEXT,0,PTXT,"ylabels dist",
  248.         33,8,   "Font ",    4,MTEXT,0,PTXT,"ylabels font",
  249.         43,8,   "Color ",   7,MTEXT,0,PTXT,"ylabels color",
  250.         58,8,   "",     6,MSUB,102,"Ynames","ynames",
  251.         66,8,   "Grid ",    3,MTOGOFF,SS,PTXT,"yaxis grid",
  252.  
  253.         1,10,   "",     6,MSUB,105,"X2axis","x2axis",
  254.         16,10,  "",     6,MSUB,106,"Y2axis","y2axis",
  255.         31,10,  "",     3,MSUB,108,"Bar","bar",
  256.         46,10,  "",     4,MSUB,107,"Fill","fill",
  257.         61,10,  "",     3,MSUB,109,"Let","let",
  258.         70,10,  "",     6,MSUB,110,"Xtra's","xtra",
  259.  
  260.         1,12,   "Data Files",   0,MNULL,0,PTXT,"",
  261.         23,12,  "Dn Marker    Lstyle Color Lwidth Smooth  Keytext     Err",
  262.                                 0,MNULL,0,PTXT,"",
  263.         0,0,"",         0,MEND,0,0,""
  264. };
  265. int refresh_menu(struct menu_struct *m);
  266. int menu_hilight(struct menu_struct *m);
  267. int menu_norm(struct menu_struct *m);
  268.  
  269. /* menu's
  270.         topmenu
  271.                 title,xtitle,ytitle min max dist on off, ticks dticks
  272.                 (2) let d = exp
  273.                 Data files
  274.                 Dn marker ,color, lwidth, lstyle, err,
  275.         xnamesmenu
  276.         ynamesmenu
  277.         fillmenu
  278.         barmenu
  279.         axismenu's
  280. */
  281. read_default(char *result, char *ques, char *dflt)
  282. {
  283.         char s[200];
  284.         int r;
  285.         strcpy(s,ques); strcat(s," ["); strcat(s,dflt); strcat(s,"] ");
  286.         r = read_input(result,s);
  287.         if (strlen(result)==0) strcpy(result,dflt);
  288.         return r;
  289. }
  290. extern int changed;
  291. addline(char *s)
  292. {
  293.         changed = true;
  294.         vinsert(ngtxt+1,s);
  295. }
  296. char *mark_names[] = {
  297.         "dot", "square", "fcircle", "club", "diamond", "triangle", "snake"
  298.         ,"otimes", "odot", ""};
  299.  
  300. idiot_questions()
  301. {
  302.         char s1[80],ss1[60],ss2[60],ss[100];
  303.         char s2[80];
  304.         int m,i,nd,domark;
  305.  
  306.         scr_norm();
  307.         window(1,1,80,25);
  308.         clrscr();
  309.         gotoxy(1,1);
  310. /*  scr_menuval(); */
  311.  
  312. #define dflt(v1,v2,v3) if (read_default(v1,v2,v3)) goto abort_idiot
  313.  
  314.         addline("amove 0 0");
  315.         addline("begin graph");
  316.         wprintf("   Answer the following questions to set up a simple graph\n");
  317.         wprintf("   (press return for defaults)\n\n");
  318.         dflt(s1,"Width of graph in cm","24");
  319.         dflt(s2,"Height of graph in cm","18");
  320.         sprintf(ss,"    size %s %s",s1,s2); addline(ss);
  321.         dflt(s1,"How many data files do you have to graph","1");
  322.         nd = atoi(s1);
  323.         for (i=0;i<nd; i++) {
  324.                 dflt(s1,"Name of data file","*.dat"); strcpy(s2,s1);
  325.                 if (strchr(s1,'*')!=NULL)  {
  326.                         screen_save();
  327.                         pick_file(s2,s1);
  328.                         screen_restore();
  329.                 }
  330.                 sprintf(ss,"    data %s",s2); addline(ss);
  331.         }
  332.         dflt(s1,"Xaxis min","auto-scale");
  333.         dflt(s2,"Xaxis max","auto-scale");
  334.         ss1[0] = 0; ss2[0] = 0;
  335.         if (strcmp(s1,"auto-scale")!=0) sprintf(ss1,"min %s ",s1);
  336.         if (strcmp(s2,"auto-scale")!=0) sprintf(ss2,"max %s ",s2);
  337.         sprintf(ss,"    xaxis %s %s ",ss1,ss2); addline(ss);
  338.  
  339.         dflt(s1,"Yaxis min","auto-scale");
  340.         dflt(s2,"Yaxis max","auto-scale");
  341.         ss1[0] = 0; ss2[0] = 0;
  342.         if (strcmp(s1,"auto-scale")!=0) sprintf(ss1,"min %s ",s1);
  343.         if (strcmp(s2,"auto-scale")!=0) sprintf(ss2,"max %s ",s2);
  344.         sprintf(ss,"    yaxis %s %s ",ss1,ss2); addline(ss);
  345.  
  346.         dflt(s1,"How many datasets do you want to draw lines or markers for","1");
  347.         nd = atoi(s1);
  348.         dflt(s1,"Do you want lines drawn for these datasets","no");
  349.         ss1[0] = 0;
  350.         if (tolower(*s1)=='y') strcpy(ss1,"lstyle 1");
  351.         dflt(s1,"Do you want markers drawn for these datasets","yes");
  352.         domark = false;
  353.         strcpy(ss2,"marker");
  354.         if (tolower(*s1)=='y') domark=true;
  355.  
  356.         for (i=0, m=0;i<nd;i++,m++) {
  357.                 if (m>8) m=0;
  358.                 if (!domark) {strcpy(ss2,""); m=9;}
  359.                 sprintf(ss,"    d%d %s %s %s",i+1,ss1,ss2,mark_names[m]);
  360.                 addline(ss);
  361.         }
  362. abort_idiot:;
  363.         addline("end graph");
  364. }
  365. int init_menucolor(void);
  366. int m_gstart,m_gend,m_dontdraw;
  367. menu()
  368. {
  369.         int nop=0,i,cc;
  370.         char dd[20],dd2[6],ds[3];
  371.         menutype *mi;
  372.  
  373.         init_menucolor();
  374.  
  375.         pmenu[0].menu = &graphmenu[0];
  376.         pmenu[1].menu = &xnamesmenu[0];
  377.         pmenu[2].menu = &ynamesmenu[0];
  378.         pmenu[3].menu = &x2namesmenu[0];
  379.         pmenu[4].menu = &y2namesmenu[0];
  380.         pmenu[5].menu = &x2axismenu[0];
  381.         pmenu[6].menu = &y2axismenu[0];
  382.         pmenu[7].menu = &fillmenu[0];
  383.         pmenu[8].menu = &barmenu[0];
  384.         pmenu[9].menu = &letmenu[0];
  385.         pmenu[10].menu = &xtramenu[0];
  386.  
  387.         initmenu();
  388.         token_space();
  389. /*  * Find begin...end graph commands */
  390.  
  391.         for (i=1;i<=ngtxt;i++) {
  392.                 strcpy(srclin,(*gtxt)[i]);
  393.                 token(srclin,(TOKENS) tk,&ntk,outbuff);
  394.  
  395. #if (defined EMXOS2 || defined DJ)                              /* a.r. */
  396.         /* quick hack a.r., prevents crash if F9 pressed before Fwhatever */
  397.                 if (tk[1] == '\0')  {tk[1] = tk[2] = "Grrrr!";}
  398. #endif
  399.                 if (strcmp(tk[1],"BEGIN")==0  && strcmp(tk[2],"GRAPH")==0)
  400.                         nop++;
  401.         }
  402.  
  403. /*  * Ask user which graph to edit  1...n */
  404.         {
  405.         pmenutype ask;
  406.         menutype *m;
  407.         char bb[20];
  408.                 ask.ci = 0;
  409.                 ask.menu = myallocn(1,sizeof(menutype)*10);
  410.                 m = ask.menu;
  411.                 for (i=0;i<=nop;i++,m++) {
  412.                         sprintf(bb,"Graph %d",i+1);
  413.                         setmenu(m,10,6+(i*2),MRETURN,0,0,"",bb,"gle loadgraph");
  414.                         if (i==nop) m->val = sdup("Add/Create new Graph");
  415.                         m->width = strlen(m->val);
  416.                 }
  417.                 setmenu(m,2,1,MNULL,0,0
  418.                         ,"Select the graph in your file which you want to change (1=first graph)"
  419.                         ,"","gle loadgraph");
  420.                 m++;
  421.                 setmenu(m,2,22,MNULL,0,0
  422.                         ,"Use ^Z (Control+Z) to exit from each form"
  423.                         ,"","gle loadgraph");
  424.                 if (do_menu(&ask)) return;
  425.                 i = ask.ci;
  426.                 myfree(ask.menu);
  427.         }
  428.  
  429.         m_gstart = ngtxt+1;
  430.         m_gend = ngtxt;
  431.         if (i<nop) fillinmenu(i+1); else {
  432.                 getsize();
  433.                 idiot_questions();
  434.                 return;
  435.         }
  436.         do_menu(&pmenu[0]);
  437.         extractmenu();
  438.         clrscr();
  439. }
  440. /*
  441.  
  442.         Getkey/command
  443.                 arrowkeys normal
  444.                 left and right arrow if editing
  445.                 delete
  446.                 insert normal character
  447.                 enter, change to new menu
  448.                 escape exit.
  449.                 F1, help key
  450. */
  451. char mbuff[255];
  452.  
  453. extern int iserr;
  454. int hcx,cx,hcy; /* HIlighted current x,y */
  455. do_menu(pmenutype *ppmenu)
  456. {
  457.         menutype *cm,*cmi,*si=NULL,*mi;
  458.         int citem,emode=false;
  459.         int c;
  460.         cm = ppmenu->menu;
  461.         citem = ppmenu->ci;
  462.         cmi = cm+citem;
  463.         refresh_menu(cm);
  464.         menu_hilight(cmi);
  465.         for (;;) {
  466.          c = text_inkey();
  467.          if (iserr) {fner_clear(); window(1,1,80,24);}
  468.          switch (c) {
  469.            case eescape: /* ESCAPE */
  470.            case equit: /* control c */
  471.                 return true;
  472.            case eleft: /* left */
  473.                 if (emode) {
  474.                         if (cx>0) cx--;
  475.                         gotoxy(hcx+cx,hcy);
  476.                 } else {
  477.                         for (si=NULL,mi=cm;mi->typ!=0;mi++) {
  478.                                 if (mi->y==cmi->y && mi->x < cmi->x)
  479.                                 if (si!=NULL) {
  480.                                         if (mi->x > si->x)
  481.                                                 si = mi;
  482.                                 } else si = mi;
  483.                         }
  484.                 }
  485.                 break;
  486.            case eright: /* right */
  487.                 if (emode) {
  488.                         if (cx < strlen(cmi->val)) cx++;
  489.                         gotoxy(hcx+cx,hcy);
  490.                 } else {
  491.                         for (si=NULL,mi=cm;mi->typ!=0;mi++) {
  492.                                 if (mi->y==cmi->y && mi->x > cmi->x)
  493.                                 if (si!=NULL) {
  494.                                         if (mi->x < si->x)
  495.                                                 si = mi;
  496.                                 } else si = mi;
  497.  
  498.                         }
  499.                 }
  500.                 break;
  501.            case eup: /* arrow up */
  502.                 emode = false;
  503.                 for (si=NULL,mi=cm;mi->typ!=0;mi++) {
  504.                         if (mi->typ<MNULL) {
  505.                          if (si!=NULL) if (mi->y==si->y)
  506.                            if (abs(mi->x - cmi->x) <  abs(si->x - cmi->x))
  507.                                 si = mi;
  508.                          if (mi->y < cmi->y) if (si!=NULL) {
  509.                            if (mi->y > si->y) si = mi;
  510.                          } else   si = mi;
  511.                         }
  512.                 }
  513.                 break;
  514.            case edown: /* arrow down */
  515.                 emode = false;
  516.                 for (si=NULL,mi=cm;mi->typ!=0;mi++) {
  517.                         if (mi->typ<MNULL) {
  518.                          if (si!=NULL) if (mi->y==si->y)
  519.                            if (abs(mi->x - cmi->x) <  abs(si->x - cmi->x))
  520.                                 si = mi;
  521.                          if (mi->y > cmi->y) if (si!=NULL) {
  522.                            if (mi->y < si->y) si = mi;
  523.                          } else  si = mi;
  524.                         }
  525.                 }
  526.                 break;
  527.           case ehelp: /* f1 help */
  528.                 do_help(cmi->help);
  529.                 refresh_menu(cm);
  530.                 menu_hilight(cmi);
  531.                 break;
  532.           case ereturn: /* carriage return */
  533.                 if (emode==true && cmi->typ==MFILE) {
  534.                         emode = false;
  535.                         break;
  536.                 }
  537.                 emode = false;
  538. doreturn:;
  539.                 switch (cmi->typ) {
  540.                   case MTEXT:
  541. /*          if (emode) emode = false; else emode = true; */
  542.                         break;
  543.                   case MTOGON:
  544.                         cmi->typ = MTOGOFF;
  545.                         menu_hilight(cmi);
  546.                         break;
  547.                   case MTOGOFF:
  548.                         cmi->typ = MTOGON;
  549.                         menu_hilight(cmi);
  550.                         break;
  551.                   case MRETURN:
  552.                         goto exit_menu;
  553.                   case MFILE:
  554.                         if (mystrlen(cmi->val)==0) cmi->val = myalloc(20);
  555.                         pick_file(cmi->val,"*.dat");
  556.                         refresh_menu(cm);
  557.                         menu_hilight(cmi);
  558.                         break;
  559.                   case MSUB: /* SUB MENU */
  560.                         if (cmi->typ2>99) do_menu(&pmenu[cmi->typ2 - 100]);
  561.                         refresh_menu(cm);
  562.                         menu_hilight(cmi);
  563.                 }
  564.  
  565.                 for (si=NULL,mi=cm;mi->typ!=0;mi++) {
  566.                         if (mi->y==cmi->y && mi->x > cmi->x)
  567.                         if (si!=NULL) {
  568.                                 if (mi->x < si->x)
  569.                                         si = mi;
  570.                         } else si = mi;
  571.                 }
  572.  
  573.                 break;
  574.           case edelete: /* delete */
  575.                 emode = true;
  576.                 if (cmi->val==NULL) break;
  577.                 if (strlen(cmi->val)==0) break;
  578.                 if (cx<1) break;
  579.                 ncpy(mbuff,cmi->val,cx-1);
  580.                 strcat(mbuff,cmi->val + cx);
  581.                 setvstr(&cmi->val,mbuff);
  582.                 cx--;
  583.                 gotoxy(hcx+cx,hcy);
  584.                 cputs(cmi->val + cx);
  585.                 putch(DASHCHAR);
  586.                 gotoxy(hcx+cx,hcy);
  587.                 break;
  588.           case edrawit:
  589.                 if (m_dontdraw)  break;
  590.                 extractmenu();
  591.                 window(1,1,79,24);
  592.                 scr_grey();
  593.                 clrscr();
  594.                 gotoxy(1,1);
  595.                #ifndef EMXOS2                           /* a.r. */
  596.                 gle_redraw();
  597.                #else
  598.                 g_get_type(devtype);
  599.                 if (strstr(devtype, "HARDCOPY") == NULL)
  600.                        {
  601.                         if ( oldSession != 0 ) 
  602.                                 stopPMSession(oldSession);
  603.                         text_saveOS2tmp();
  604.                         oldSession = startPMSession();
  605.                        }
  606.                 else
  607.                         gle_redraw();
  608.                #endif
  609.                 refresh_menu(cm);
  610.                 menu_hilight(cmi);
  611.                 break;
  612.           case eshowerror:
  613.                 text_showerror();
  614.                 refresh_menu(cm);
  615.                 menu_hilight(cmi);
  616.                 break;
  617.           case esave: /* save file */
  618.                 extractmenu();
  619.                 text_save();
  620.                 break;
  621.           default: /* normal key */
  622.                 if (c<26  && c!=9) {fner("Key has no affect"); break;}
  623.                 if (c>200)  fner("Unimplemented command");
  624.                 else {
  625. /*  if (cmi->typ!=MTEXT  && cmi->typ!=MFILE) goto doreturn; */
  626.                         emode = true;
  627.                         if (cmi->val==NULL) setvstr(&cmi->val,"");
  628.                         ncpy(mbuff,cmi->val,cx);
  629.                         mbuff[cx] = c; mbuff[cx+1] = 0;
  630.                         strcat(mbuff,cmi->val + cx);
  631.                         setvstr(&cmi->val,mbuff);
  632.                         gotoxy(hcx+cx,hcy);
  633.                         cputs(cmi->val + cx);
  634.                         cx++;
  635.                         gotoxy(hcx+cx,hcy);
  636.                 }
  637.                 break;
  638.          }
  639.          if (si!=NULL) {
  640.                 menu_norm(cmi);
  641.                 cmi = si;
  642.                 menu_hilight(cmi);
  643.                 si = NULL;
  644.          }
  645.         }
  646. exit_menu:;
  647.         /* save current point */
  648.         { int i;
  649.                 for (i=0,mi=cm;mi->typ!=0;mi++,i++) {
  650.                   if (mi==cmi) ppmenu->ci = i;
  651.                 }
  652.         }
  653.         return false; /* normal exit */
  654. }
  655. setvstr(char **d, char *s)
  656. {
  657.         if ((*d) != 0) myfree(*d);
  658.         *d = sdup(s);
  659. }
  660. int mystrlen(char *s)
  661. {
  662.         if (s==NULL) return 0;
  663.         else return strlen(s);
  664. }
  665. menu_hilight(struct menu_struct *mm)
  666. {
  667.         int i,j;
  668.         struct menu_struct *m=mm;
  669.         scr_menuhi();
  670.         hcx = m->x + mystrlen(m->title);
  671.         hcy = m->y;
  672.         gotoxy(hcx,hcy);
  673.         if (m->typ==MTOGON || m->typ==MTOGOFF) {
  674.                 if (m->val==NULL) m->val = myalloc(4);
  675.                 if (m->typ==MTOGON) strcpy(m->val,"ON ");
  676.                 if (m->typ==MTOGOFF) strcpy(m->val,"OFF");
  677.         }
  678.         if (m->val==NULL) setvstr(&m->val,"");
  679.         cputs(m->val);
  680.         j = m->width - mystrlen(m->val);
  681.         printdash(j);
  682.         cx = mystrlen(m->val);
  683.         gotoxy(hcx+cx,hcy);
  684. }
  685. printdash(int j)
  686. {
  687.         int i;
  688.         for (i=0;i<j;i++) mbuff[i] = DASHCHAR;
  689.         mbuff[j] = 0;
  690.         if (j>0) cputs(mbuff);
  691. }
  692. menu_norm(struct menu_struct *mm)
  693. {
  694.         int i,j;
  695.         struct menu_struct *m=mm;
  696.         gotoxy(m->x + mystrlen(m->title),m->y);
  697.         if (m->typ==MTOGON  || m->typ==MTOGOFF) {
  698.                 if (m->val==NULL) m->val = myalloc(4);
  699.                 if (m->typ==MTOGON) strcpy(m->val,"ON ");
  700.                 if (m->typ==MTOGOFF) strcpy(m->val,"OFF");
  701.         }
  702.         if (m->val != NULL) {
  703.                 scr_menuval();
  704.                 if (m->width>0) cputs(m->val);
  705.                 scr_menubg();
  706.         }
  707.         j = m->width - mystrlen(m->val);
  708.         printdash(j);
  709. }
  710. refresh_menu(struct menu_struct *mm)
  711. {
  712.         int i;
  713.         struct menu_struct *m=mm;
  714.         window(1,1,80,24);
  715.         scr_menubg();
  716.         clrscr();
  717.         for (;m->typ!=0;m++) {
  718.                 if (m->title != NULL) if (strlen(m->title)>0) {
  719.                         gotoxy(m->x,m->y);
  720.                         cputs(m->title);
  721.                 }
  722.                 menu_norm(m);
  723.         }
  724. }
  725. extern char *tk[500];
  726. extern char inbuff[300];
  727. extern char tkbuff[500];
  728. extern char space_str[3];
  729. extern int ntk;
  730.  
  731. do_help(char *hstr)
  732. {
  733.         char ss[90];
  734.         strcpy(ss,"gle graph ");
  735.         strcat(ss,hstr);
  736.         do_help2(ss);
  737. }
  738. int fread_str(char *hbuff,int count, FILE *hidx);
  739. int fread_str(char *hbuff,int count, FILE *hidx)
  740. {
  741.         int i,slen;
  742.         hbuff[0] = 0;
  743.         i = fread(&slen,sizeof(slen),1,hidx);
  744.         if (i<=0) return i;
  745.         i = fread(hbuff,1,slen,hidx);
  746.         hbuff[slen] = 0;
  747.         return i;
  748. }
  749. do_help2(char *h)
  750. {
  751.         FILE *hfile,*hidx;
  752.         int32 hpnt,fipnt;
  753.         int i,yy,cp,match,capture;
  754.         char hbuff[91],mstr[90],mstr2[90],fk1[91];
  755.         char hstr[91],*s,*ss,hstr2[91];
  756.         char *hfilename="graph.hlp";
  757.         char subtopic[2000];
  758.         int atend;
  759.  
  760.         window(1,1,80,24);
  761.         strcpy(hstr,h);
  762.  
  763.         gotoxy(1,1);    scr_menuval();
  764.         clreol(); wprintf("   Working..."); scr_refresh();
  765.         hfile = fopen(gledir(hfilename),"r");
  766.         if (hfile==NULL) {perror("Unable to open graph.hlp "); return;}
  767.         hidx = fopen(gledir("graph.idx"),"rb");
  768.         if (hidx==NULL) {perror("Unable to open graph.idx "); return;}
  769. help_again:;
  770.         rewind(hidx);
  771.         gotoxy(1,1);    scr_menuval();
  772.         clreol(); wprintf("   Working..."); scr_refresh();
  773.         subtopic[0] = 0;
  774.         strcpy(hstr2,hstr); token_data(hstr2,tk,&ntk,tkbuff);
  775.         for (i=1;i<=ntk;i++) strlwr(tk[i]);
  776.  
  777.         /* clear(); */
  778.         clrscr();
  779.  
  780.         if (ntk<2) tk[2] = "";
  781.         if (ntk<3) tk[3] = "";
  782.         if (*tk[2] == 'd' && strlen(tk[2])==2) tk[2] = "dn";
  783.         if (strcmp(tk[3],"yaxis")==0) tk[3] = "xaxis";
  784.         if (strcmp(tk[3],"y2axis")==0) tk[3] = "xaxis";
  785.         if (strcmp(tk[3],"x2axis")==0) tk[3] = "xaxis";
  786.         if (strcmp(tk[3],"ylabels")==0) tk[3] = "xlabels";
  787.         if (strcmp(tk[3],"y2labels")==0) {tk[3] = "xlabels"; tk[2] = "off";}
  788.         if (strcmp(tk[3],"x2labels")==0) {tk[3] = "xlabels"; tk[2] = "off";}
  789.         if (strcmp(tk[3],"ynames")==0) tk[3] = "xnames";
  790.         if (strcmp(tk[3],"y2names")==0) tk[3] = "xnames";
  791.         if (strcmp(tk[3],"x2names")==0) tk[3] = "xnames";
  792.         if (strcmp(tk[3],"ytitle")==0) tk[3] = "xtitle";
  793.         if (strcmp(tk[3],"y2title")==0) tk[3] = "xtitle";
  794.         if (strcmp(tk[3],"x2title")==0) tk[3] = "xtitle";
  795.         if (strcmp(tk[3],"title")==0) tk[3] = "xtitle";
  796.  
  797.         gotoxy(1,1); wprintf("GLE help ");
  798.         for (i=1;i<=ntk;i++) wprintf("{%s} ",tk[i]);
  799.         scr_menubg();
  800.  
  801.         /* Find match for each key word, display that section of file
  802.         and find rest of key words at that level */
  803.  
  804.         match = 1; /* trying to match a level one word */
  805.         capture = false;
  806.         for (;!feof(hidx);) {
  807.           if (fread_str(hbuff,90,hidx)!=0) {
  808.                 fread(&fipnt,sizeof(fipnt),1,hidx);
  809.                 sprintf(mstr,"%d",match);
  810.                 sprintf(mstr2,"%d",match-1);
  811.                 if (match>ntk) {
  812.                   strcpy(fk1,hbuff); fk1[1] = 0;
  813.                   i = atoi(fk1);
  814.                   if (i>0 && i<match) { /* End of section */
  815.                         goto got_help;
  816.                   }
  817.                   if (i>0 && i==match) { /* Sub topic */
  818.                         capture = false;
  819.                         strtok(hbuff," \t\n");
  820.                         strcat(subtopic,strtok(NULL," \t\n"));
  821.                         strcat(subtopic," ");
  822.                   }
  823.                 } else if (strncmp(hbuff,mstr,1)==0) { /* correct level */
  824.                         strtok(hbuff," \t\n");
  825.                         s = strtok(NULL," \t\n"); strcpy(fk1,s);
  826.                         strlwr(fk1);
  827.                         if (strncmp(fk1,tk[match],strlen(tk[match]))==0) {
  828.                                 match++;
  829.                                 if (match>ntk) {
  830.                                         hpnt = fipnt;
  831.                                         capture = true;
  832.                                 }
  833.                         }
  834.                 }
  835.           }
  836.         }
  837.         scr_menuval();
  838.         gotoxy(1,9);
  839.         wprintf("Help text not found, press any key to continue ??? \n");
  840.         if (text_inkey()==eescape) goto quit_help;
  841.         strcpy(hstr,"gle");
  842.         goto help_again;
  843.  
  844. got_help:;
  845.         cp = 1;
  846. next_page:
  847.         atend = help_show(hfile,hpnt,subtopic,cp);
  848.  
  849.         scr_menuval();
  850.         gotoxy(1,23);
  851.         if (subtopic[0]==0) s = "Enter '-' to go up a level ";
  852.         else s = "Subtopic ";
  853.         strcpy(mstr,s);
  854.         if (!atend) strcat(mstr,"[next page] ");
  855.         else strcat(mstr,"[press return to exit help] ");
  856.         i = read_command(hbuff,mstr);
  857.         window(1,1,80,24);
  858.         if (i==epageup) {
  859.                 cp -=16;
  860.                 if (cp<0) cp = 0;
  861.                 goto next_page;
  862.         }
  863.         if (i==epagedown) {
  864.                 cp +=16;
  865.                 if (cp<0) cp = 0;
  866.                 goto next_page;
  867.         }
  868.         scr_menubg();
  869.         strupr(hbuff);
  870.         if (hbuff[0]=='-') {
  871.                 strcpy(hstr2,hstr);
  872.                 s = strtok(hstr2," \t");
  873.                 for (;s!=NULL;) {ss = s; s = strtok(NULL," \t");}
  874.                 *strstr(hstr,ss) = 0;
  875.                 goto help_again;
  876.         }
  877.         if (strlen(hbuff)!=0) {
  878.                 strcat(hstr," ");
  879.                 strcat(hstr,hbuff);
  880.                 goto help_again;
  881.         }
  882.         if (!atend) {cp+=16; goto next_page;}
  883.  
  884. quit_help:;
  885.         fclose(hfile);
  886.         fclose(hidx);
  887. }
  888. int help_show(FILE *hfile, int32 hpnt, char *st, int cp)
  889. {
  890.         int i=1,sl=3;
  891.         int lvl= -1;
  892.         char hbuff[100],*s;
  893.         char subtopic[2000];
  894.  
  895.         strcpy(subtopic,st);
  896.         fseek(hfile,hpnt,SEEK_SET);
  897.         window(1,1,80,24);
  898.         clrscr();
  899.         scr_menuval();
  900.         gotoxy(1,1); wprintf("GLE help ");
  901.         for (i=1;i<=ntk;i++) wprintf("{%s} ",tk[i]);
  902.         scr_menubg();
  903.         for (;!feof(hfile) && sl<18;) {
  904.           if (fgets(hbuff,90,hfile)!=NULL) {
  905.                 lvl = hbuff[0]-'0';
  906.                 if (lvl>0 && lvl<9) goto end_section;
  907.                 if (i>cp) {
  908.                         gotoxy(1,sl++); cputs(tabtospace(hbuff));
  909.                 }
  910.                 i++;
  911.           }
  912.         }
  913. end_section:
  914.         if (strlen(subtopic)==0) goto skip_sub;
  915.  
  916.         sl++;
  917.         gotoxy(1,sl++); cputs("Subtopics:");
  918.  
  919.         s = strtok(subtopic," \t\n");
  920.         for (i=1;s!=NULL;i++) {
  921.           if (i==1) strcpy(hbuff,"\t");
  922.           if (strcmp(s,"(end)")!=0) {
  923.                 strcat(hbuff,s); strcat(hbuff,"\t");
  924.                 if (strlen(s)>7) i++;
  925.                 if (i>6) {
  926.                         gotoxy(1,sl++); cputs(tabtospace(hbuff));
  927.                         hbuff[0] = 0;
  928.                         i = 0;
  929.                         if (sl>21) return false;
  930.                 }
  931.           }
  932.           s = strtok(NULL," \t\n");
  933.         }
  934.         gotoxy(1,sl++); cputs(tabtospace(hbuff));
  935. skip_sub:;
  936.         if (!(lvl>0 && lvl<9) ) return false;
  937.         return true; /* not finished */
  938. }
  939. add_unrecognized(char *s)
  940. {
  941.         if (nunrec>6) return;
  942.         xtramenu[nunrec++].val = sdup(s);
  943. }
  944. int vunquote(char **s);
  945. vunquote(char **ss)
  946. {
  947.         char *s = *ss;
  948.         if (*s=='\"') {
  949.                 s[strlen(s)-1] = 0;
  950.                 *ss = sdup(s+1);
  951.                 myfree(s);
  952.         }
  953. }
  954.  
  955. int initmenudone;
  956. menutype *m_pnt[20];
  957. menutype *m_end[20];
  958. char *m_val[20];
  959. char m_tog[50];
  960. initmenu()
  961. {
  962.         menutype *mi;
  963.         char *s,kw1[80],kw2[80];
  964.         int i,j,nt=0,k,z,ct,used;
  965.         static int nv;
  966.  
  967.         if (!initmenudone) {
  968.           minit_extras();
  969.           initmenudone = true;
  970.           for (z=0;z<=10;z++) {
  971.                 for (mi=pmenu[z].menu; mi->typ!=0; mi++) {
  972.                 if (mi->typ==MTOGON || mi->typ==MTOGOFF) {
  973.                         m_tog[nt++] = mi->typ;
  974.                 }
  975.                 if (mi->val!=NULL) {
  976.                         m_val[nv] = sdup(mi->val);
  977.                         mi->val = sdup(mi->val);
  978.                         m_pnt[nv++] = mi;
  979.                 }
  980.                 }
  981.           }
  982.         } else {
  983.           for (z=0;z<=10;z++) {
  984.                 for (mi=pmenu[z].menu; mi->typ!=0; mi++) {
  985.                 if (mi->typ==MTOGON || mi->typ==MTOGOFF) {
  986.                         mi->typ = m_tog[nt++];
  987.                 } else {
  988.                         if (mi->val!=0) {
  989.                                 myfree(mi->val);
  990.                         }
  991.                         mi->val = 0;
  992.                 }
  993.                 }
  994.           }
  995.           for (z=0;z<nv;z++) {
  996.                 mi = m_pnt[z];
  997.                 mi->val = sdup(m_val[z]);
  998.           }
  999.         }
  1000. }
  1001.  
  1002. minit_extras()
  1003. {
  1004.         char dd[29],dd2[9],ds[9];
  1005.         menutype *mi;
  1006.         int i;
  1007.  
  1008.         i = 0;
  1009.         for (mi=graphmenu;mi->typ!=0;mi++) i++;
  1010.         for (i=0;i<9;i++) {
  1011.           setmenu(mi,2,13+i,MFILE,SROL,20,"",0,"data");mi++;
  1012.         }
  1013.         for (i=0;i<9;i++) {
  1014.          sprintf(ds,"d%d ",i);
  1015.          if (i==0) strcpy(ds,"dn ");
  1016.          sprintf(dd,"%smarker",ds); setmenu(mi,23,13+i,MTEXT,0,10,ds,0,dd); mi++;
  1017.          sprintf(dd,"%slstyle",ds); setmenu(mi,37,13+i,MTEXT,0,4,"",0,dd); mi++;
  1018.          sprintf(dd,"%scolor",ds);  setmenu(mi,42,13+i,MTEXT,0,7,"",0,dd); mi++;
  1019.          sprintf(dd,"%slwidth",ds); setmenu(mi,50,13+i,MTEXT,0,4,"",0,dd); mi++;
  1020.          sprintf(dd,"%ssmooth",ds); setmenu(mi,56,13+i,MTOGOFF,SS,3,"",0,dd); mi++;
  1021.          sprintf(dd,"%skey",ds);    setmenu(mi,60,13+i,MTEXT,SSTR,15,"",0,dd); mi++;
  1022.          sprintf(dd,"%serr",ds);    setmenu(mi,76,13+i,MTEXT,0,3,"",0,dd); mi++;
  1023.          sprintf(dd,"%serrup",ds);  setmenu(mi,78,13+i,MTEXT,0,0,"",0,dd); mi++;
  1024.          sprintf(dd,"%serrdown",ds); setmenu(mi,78,13+i,MTEXT,0,0,"",0,dd); mi++;
  1025.          sprintf(dd,"%smsize",ds); setmenu(mi,78,13+i,MTEXT,0,0,"",0,dd); mi++;
  1026.          sprintf(dd,"%smscale",ds); setmenu(mi,78,13+i,MTEXT,0,0,"",0,dd); mi++;
  1027.          sprintf(dd,"%serrwidth",ds); setmenu(mi,78,13+i,MTEXT,0,0,"",0,dd); mi++;
  1028.         }
  1029. }
  1030. char msend[200];
  1031. #define mss msend+strlen(msend)
  1032. char cs[80]="xyz";
  1033. int gstartend;
  1034. extractmenu()
  1035. {
  1036.         menutype *mi;
  1037.         char *s,kw1[80],kw2[80];
  1038.         int i,j,k,z,ct,used;
  1039.  
  1040.         if ((m_gstart==0) && (m_gend==0)) return;
  1041.         gstartend = m_gstart;
  1042.         for (i=gstartend;i<=m_gend;i++) vdelete(gstartend);
  1043.  
  1044.         if (graphmenu[2].val!=NULL) {
  1045.           if (strcmp(graphmenu[2].val,"")!=0) {
  1046.                 sprintf(msend,"amove %s %s ",graphmenu[2].val,graphmenu[3].val);
  1047.                 m_sendline();
  1048.           }
  1049.         }
  1050.         sprintf(msend,"begin graph ");
  1051.         m_sendline();
  1052.         for (z=0;z<=10;z++) {
  1053.           for (mi=pmenu[z].menu; mi->typ!=0; mi++) {
  1054.                 if (mi->typ < MSUB  && mi->val!=NULL) {
  1055.                  if (strcmp(mi->val,"")!=0) {
  1056.                   ncpy(kw1,mi->help,strcspn(mi->help," "));
  1057.                   strcpy(kw2,"");
  1058.                   if (strlen(kw1)<strlen(mi->help))
  1059.                 strcpy(kw2,mi->help + strlen(kw1) + 1);
  1060.                   switch (mi->typ2) {
  1061.                 case SSIZE:
  1062.                         m_sendline();
  1063.                         sprintf(msend,"\tsize %s %s ",mi->val,(mi+1)->val);
  1064.                         mi++;
  1065.                         m_sendline();
  1066.                         break;
  1067.                 case SNOBOX:
  1068.                         if (mi->typ==MTOGOFF) {
  1069.                                 m_sendline();
  1070.                                 sprintf(msend,"\tnobox ");
  1071.                                 m_sendline();
  1072.                         }
  1073.                         break;
  1074.                 case SNEXTS:
  1075.                         m_sendline();
  1076.                         strcpy(cs,kw1);
  1077.                         sprintf(mss,"\t%s \"%s\" ",kw1,mi->val);
  1078.                         break;
  1079.                 case SROL:
  1080.                         m_sendline();
  1081.                         if (strcmp(kw1,"xtra")==0) {
  1082.                                 sprintf(mss,"\t%s",mi->val);
  1083.                         } else {
  1084.                                 sprintf(mss,"\t%s %s",kw1,mi->val);
  1085.                         }
  1086.                         break;
  1087.                 case SSTR:
  1088.                         m_ifsend(kw1);
  1089.                         sprintf(mss,"%s \"%s\" ",kw2,mi->val);
  1090.                         break;
  1091.                 case SNORM:
  1092.                         /* printf("ifsend cs={%s} k1={%s} {%s} \n",cs,kw1,kw2);*/
  1093.                         m_ifsend(kw1);
  1094.                         sprintf(mss,"%s %s ",kw2,mi->val);
  1095.                         break;
  1096.                 case STOG:
  1097.                 case SS:
  1098.                         if (mi->typ==MTOGON) {
  1099.                                 m_ifsend(kw1);
  1100.                                 sprintf(mss,"%s ",kw2);
  1101.                         }
  1102.                         break;
  1103.                 case SSOFF:
  1104.                         if (mi->typ==MTOGOFF) {
  1105.                                 m_ifsend(kw1);
  1106.                                 sprintf(mss,"%s ",kw2);
  1107.                         }
  1108.                         break;
  1109.                 case SAMOVE:
  1110.                         break;
  1111.                   }
  1112.                 }
  1113.            }
  1114.           }
  1115.         }
  1116.         m_sendline();
  1117.         sprintf(msend,"end graph");
  1118.         m_sendline();
  1119.         m_gend = gstartend-1;
  1120. }
  1121. /* char msend[200]; */
  1122. m_sendline()
  1123. {
  1124.         if (strlen(msend)>0) vinsert(gstartend++,msend);
  1125.         msend[0] = 0;
  1126.         strcpy(cs,"xyz");
  1127. }
  1128. m_ifsend(char *s)
  1129. {
  1130.         if (strcmp(s,cs)!=0) {
  1131.           m_sendline();
  1132.           sprintf(msend,"\t%s ",s);
  1133.           strcpy(cs,s);
  1134.         }
  1135. }
  1136. int g_get_usersize(double *x, double *y);
  1137. getsize()
  1138. {
  1139.         static char s1[29], s2[29];
  1140.         double x,y;
  1141. /*  g_get_usersize(&x,&y);*/
  1142.         x = 24; y = 18;
  1143.         if (x==0) return;
  1144.         sprintf(s1,"%g",x); sprintf(s2,"%g",y);
  1145.         graphmenu[0].val = sdup(s1);
  1146.         graphmenu[1].val = sdup(s2);
  1147. }
  1148. fillinmenu(int nbegin)
  1149. {
  1150.         menutype *mi;
  1151.         char *s,kw[80],mkw[80];
  1152.         int aa,i,j,k,z,nmatch=0,ct,nop=0,used,gotit;
  1153.         menutype *match[200];
  1154.         m_gstart = 0;
  1155.         nunrec = 0;
  1156. /* for each line, compare first word on line to all first words, */
  1157.         for (i=1;i<=ngtxt;i++) {
  1158.                 strcpy(srclin,(*gtxt)[i]);
  1159.                 token(srclin,(TOKENS) tk,&ntk,outbuff);
  1160.                 if (strcmp(tk[1],"AMOVE")==0) {
  1161.                         m_gstart = i;
  1162.                         graphmenu[2].val = sdup(tk[2]);
  1163.                         graphmenu[3].val = sdup(tk[3]);
  1164.                 }
  1165.                 if (strcmp(tk[1],"BEGIN")==0  && strcmp(tk[2],"GRAPH")==0) {
  1166.                         nop++;
  1167.                         if (nop==nbegin) break;
  1168.                 }
  1169.         }
  1170.         if ((m_gstart+1 !=i)  || (m_gstart==0))   m_gstart = i;
  1171.  
  1172.         pmenu[0].menu = graphmenu;
  1173.  
  1174.         for (i++;i<=ngtxt;i++) {
  1175.                 strcpy(srclin,(*gtxt)[i]);
  1176.                 token(srclin,(TOKENS) tk,&ntk,outbuff);
  1177.                 gotit = false;
  1178.                 ct = 2;
  1179.                 strcpy(kw,tk[1]);
  1180.                 strlwr(kw);
  1181.                 used = false;
  1182.                 nmatch = 0;
  1183.                 if (strcmp(tk[1],"END")==0) break;
  1184.                 for (z=0;z<10;z++) {
  1185.                 for (mi=pmenu[z].menu; mi->typ!=0; mi++) {
  1186.                   j = strlen(tk[1]);
  1187.                   if (ntk<1) if (strchr(srclin,'!')!=NULL) {
  1188.                           if (*srclin == '\t') aa=1; else aa=0;
  1189.                           add_unrecognized(srclin+aa);
  1190.                           ct = ntk + 1;
  1191.                           gotit = true;
  1192.                           goto next_xinline;
  1193.                   }
  1194.                   ct = 2;
  1195.                   if (j>1)  if (strncmp(kw,mi->help,j)==0) {
  1196.                         switch (mi->typ2) {
  1197.                           case STOG:
  1198.                           case SSTR:
  1199.                           case SSOFF:
  1200.                           case SS:
  1201.                           case SNORM: /* Just remember this one for later */
  1202.                         match[nmatch++] = mi;
  1203.                         used=true;
  1204.                         break;
  1205.                           case SNOBOX:
  1206.                         mi->typ = MTOGOFF;
  1207.                         used = true;
  1208.                         break;
  1209.                           case SSIZE:
  1210.                         mi->val = sdup(tk[2]);
  1211.                         (++mi)->val = sdup(tk[3]);
  1212.                         used = true; ct = ntk+1;
  1213.                         goto next_xinline;
  1214.                         break;
  1215.                           case SROL: /* e.g. let, bar, fill,xnames,xplaces */
  1216.                         if (mystrlen(mi->val)!=0) break;
  1217.                         k = strspn(srclin," \t");
  1218.                         k = k + strcspn(srclin+k," \t");
  1219.                         k = k + strspn(srclin+k," \t");
  1220.                         mi->val = sdup(srclin+k);
  1221.                         used=true;
  1222.                         ct = ntk+1;
  1223.                         goto next_xinline;
  1224.                           case SNEXTS: /* E.G. TITLE "XXX" ... or bar d1,d2 ...*/
  1225.                         mi->val = sdup(tk[2]);
  1226.                         vunquote(&mi->val);
  1227.                         ct = 3; used=true;
  1228.                         break;
  1229.                           case SSNULL:
  1230.                         break;
  1231.                         }
  1232.                   }
  1233.                 }
  1234.                 }
  1235. next_xinline:;
  1236.                 if (used==false && !gotit) {
  1237.                   wprintf("Warning, unrecognized graph command {%s}\n"
  1238.                                         ,tk[1]);
  1239.                   gotit = true;
  1240.                   if (*srclin == '\t') aa=1; else aa=0;
  1241.                   add_unrecognized(srclin+aa);
  1242.                 }
  1243.                 used = true;
  1244.                 for (j=ct;j<=ntk;j++) {
  1245.                   used = false;
  1246.                   strcpy(kw,tk[j]);
  1247.                   strlwr(kw);
  1248.                   for (k=0;k<nmatch;k++) {
  1249.                         mi = match[k];
  1250. /* gprint("match {%s} {%s}  {%s} \n",kw,mi->help,srclin); */
  1251.                         switch (mi->typ2) {
  1252.                           case STOG:
  1253.                         if (strcmp(kw,"on")==0) {mi->typ = MTOGON; used=true;}
  1254.                         if (strcmp(kw,"off")==0) {mi->typ = MTOGOFF; used=true;}
  1255.                         break;
  1256.                           default:
  1257.                         strcpy(mkw,mi->help);
  1258.                         s = strtok(mkw," "); s = strtok(0," ");
  1259.                         if (s!=NULL) if (strcmp(s,"lstyle")==0)
  1260.                           if (strcmp(kw,"line")==0) {mi->val = sdup("1"); used=true;}
  1261.                         if (s!=NULL) if (strcmp(s,kw)==0) {
  1262.                                 if (mi->typ2 == SS || mi->typ2 == SSOFF) {
  1263.                                         mi->typ = MTOGON;
  1264.                                         if (mi->typ2==SSOFF) mi->typ = MTOGOFF;
  1265.                                         used = true;
  1266.                                 } else {
  1267.                                  used = true;
  1268.                                  mi->val = sdup(tk[j+1]);
  1269.                                  j++;
  1270.                                  vunquote(&mi->val);
  1271.                                 }
  1272.                         }
  1273.                         }
  1274.                   }
  1275.                   /*      if (used==false && !gotit) {
  1276.                           if (*srclin == '\t') aa=1; else aa=0;
  1277.                           add_unrecognized(srclin+aa);
  1278.                           wprintf("\n lost command {%s} \n",tk[j]);
  1279.                           gotit = true;
  1280.                           wprintf("Press a key\n"); text_inkey();
  1281.                   }*/
  1282.                 }
  1283.         }
  1284.         m_gend = i;
  1285. /*  * Rad in graph commands, for each initial key word
  1286.                 compare to all menu keywords and if match is RESTOFLINE
  1287.                 type then (set item to occupied )
  1288.                 and copy rest of line into value part of menu.
  1289.                 else add to list of matches:
  1290.                 for each word in rest of line compare to each
  1291.                 matched item, and if match then put in menu value.
  1292.                 (if first keyword not found then add too not
  1293.                 understood list to be written out at end)
  1294.                 (if second word not matched then print warning message)
  1295. */
  1296. }
  1297. setmenu(menutype *m,int x, int y, int typ, int typ2, int width, char *title
  1298. , char *val, char *help)
  1299. {
  1300.         m->x = x; m->y = y; m->typ = typ; m->typ2 = typ2; m->width = width;
  1301.         m->title = sdup(title);
  1302.         if (val!=0) m->val = sdup(val);
  1303.         m->help = sdup(help);
  1304. }
  1305. init_menucolor()
  1306. {
  1307.                 h_bcolor = WHITE; h_fcolor = BLACK;
  1308. }
  1309. static int saveplace;
  1310. int pick_file(char *result, char *wld)
  1311. {
  1312.         pmenutype ask;
  1313.         char wild[80];
  1314.         char buff2[80];
  1315.         char *f[80];
  1316.         char *swap;
  1317.         menutype *m,*mi,*mwild;
  1318. #ifndef EMXOS2                                  /* a.r. */
  1319.         struct ffblk ffblk;
  1320. #else
  1321.         HDIR            hdir;
  1322.         FILEFINDBUF3    FFbufr;
  1323.         unsigned long   SearchCnt;
  1324. #endif
  1325.         int done,i,x,y,nf,rval,adddir=false;
  1326.  
  1327.         strcpy(wild,wld);
  1328.         ask.ci = saveplace;
  1329. pick_again:;
  1330.         x=0; y=0; nf=0;
  1331.         init_menucolor();
  1332. #ifndef EMXOS2                                  /* a.r. */
  1333.         done = findfirst(wild,&ffblk,0);
  1334.         for (nf=0;nf<70 && !done;nf++) {
  1335.                 f[nf] = sdup(ffblk.ff_name);
  1336.                 done = findnext(&ffblk);
  1337.         }
  1338. #else
  1339.         SearchCnt = 1; 
  1340.         hdir = HDIR_SYSTEM; 
  1341.         done = DosFindFirst(    wild,
  1342.                                 &hdir,
  1343.                                 0,
  1344.                                 &FFbufr,
  1345.                                 sizeof(FFbufr),
  1346.                                 &SearchCnt,
  1347.                                 FIL_STANDARD);
  1348.         for (nf=0;nf<70 && !done;nf++) {
  1349.                 f[nf] = sdup(FFbufr.achName);
  1350.                 done = DosFindNext( hdir,
  1351.                                     &FFbufr,
  1352.                                     sizeof(FFbufr),
  1353.                                     &SearchCnt);
  1354.                 }
  1355. #endif
  1356. sortagain:;
  1357.         swap = NULL;
  1358.         for (i=0;i<(nf-1);i++) {
  1359.                 if (strcmp(f[i],f[i+1])>0) {
  1360.                         swap = f[i]; f[i] = f[i+1]; f[i+1] = swap;
  1361.                 }
  1362.         }
  1363.         if (swap != NULL) goto sortagain;
  1364.  
  1365.         m = myallocn(3+nf,sizeof(*m));
  1366.         ask.menu = m;
  1367.         ask.ci = saveplace;
  1368.         if (saveplace>nf) ask.ci = 0;
  1369.         if (nf==0) ask.ci = 1;
  1370.         if (m==0) wprintf("memory allocation error");
  1371.         for (mi=m,i=0;i<nf;i++,mi++) {
  1372.                 setmenu(mi,x*20+1,y+5,MRETURN,0,18,"",f[i],"");
  1373.                 x++;
  1374.                 if (x==4) {x=0; y++; }
  1375.         }
  1376.         setmenu(mi,5,1,MNULL,0,0,"Use arrow keys to select file then press return","","");
  1377.         mi++;
  1378.         setmenu(mi,5,3,MRETURN,0,30,"Disk/Dir Specification ",wild,"");
  1379.         mwild = mi;
  1380.         mi++; mi->typ = 0;
  1381.         m_dontdraw = true;
  1382.         rval = do_menu(&ask);
  1383.         saveplace = ask.ci;
  1384.         m_dontdraw = false;
  1385.         strcpy(result,((ask.menu)[ask.ci]).val);
  1386.         for (i=0;i<nf;i++) myfree(f[i]);
  1387.         myfree(m);
  1388.  
  1389.         if (strcmp(wild,mwild->val)!=0) {
  1390.                 strcpy(wild,mwild->val);
  1391.                 if (strstr(wild,"*")==NULL) {
  1392.                         if (wild[strlen(wild)-1] == '\\')
  1393.                                 strcat(wild,"*.gle");
  1394.                         else
  1395.                                 strcat(wild,"\\*.gle");
  1396.                 }
  1397.                 adddir = true;
  1398.                 goto pick_again;
  1399.         }
  1400.  
  1401.         if (adddir) {
  1402.                 *(strfile(wild)) = 0;
  1403. #if (defined __TURBOC__ || defined DJ)
  1404.                 if (strstr(wild,":")!=NULL || strlen(wild)==1) {
  1405.                         setdisk(toupper(*wild)-'A');
  1406.                         if (strlen(wild)>1)
  1407.                                 {strcpy(buff2,wild+2); strcpy(wild,buff2);}
  1408.                 }
  1409. #endif
  1410. #ifdef EMXOS2                                                    /* a.r. */
  1411.                 if (strstr(wild,":")!=NULL || strlen(wild)==1) {
  1412.                         DosSetDefaultDisk(toupper(*wild)-'A' + 1);
  1413.                         if (strlen(wild)>1)
  1414.                                 {strcpy(buff2,wild+2); strcpy(wild,buff2);}
  1415.                 }
  1416.                 if (strlen(wild)!=1) if (_chdir2(wild)!=0) {perror("Cannot change dir"); delay(3000);}
  1417. #else
  1418.                 if (strlen(wild)!=1) if (chdir(wild)!=0) {perror("Cannot change dir"); delay(3000);}
  1419. #endif
  1420.         }
  1421.  
  1422. /*  if (adddir) {
  1423.                 *(strfile(wild)+1) = 0;
  1424.                 strcpy(result,wild);
  1425.                 strcat(result,((ask.menu)[ask.ci]).val);
  1426.         }
  1427. */
  1428.         return rval;
  1429. }
  1430. char *strfile(char *s)
  1431. {
  1432.         char *e;
  1433.         e = s;
  1434.         for (;*s!=0;s++) {
  1435.                 if (*s==']'  ||  *s=='\\' || *s=='/' || *s==':') e = s;
  1436.         }
  1437.         return e;
  1438. }
  1439.